package top.hcode.hoj.dao;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.nutz.lang.Strings;
import org.sagacity.sqltoy.model.MapKit;
import org.springframework.stereotype.Service;
import top.hcode.hoj.common.LazyDao;
import top.hcode.hoj.mapper.CollUserAnswerMapper;
import top.hcode.hoj.pojo.entity.coll.CollUserAnswer;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author orangej
 * @since 2025-02-09
 */
@Service
@RequiredArgsConstructor
public class CollUserAnswerDao extends ServiceImpl<CollUserAnswerMapper, CollUserAnswer> {
    private final LazyDao dao;

    /**
     * 查询用户已答题的题目id列表
     */
    public List<String> queryAnsweredQuestionIds(String uid, String collId) {
        return baseMapper.queryAnsweredQuestionIds(uid, collId);
    }

    /**
     * 查询用户选择题得分，默认返回 0
     */
    public BigDecimal sumChoiceQuestionScore(String uid, String collId) {
        BigDecimal score = dao.selectOne(BigDecimal.class, "select sum(t0.score) from \n" +
                "(select * from coll_user_answer where user_id = ? and coll_id = ?) t0 \n" +
                "left join coll_question t1 on t0.question_id = t1.id\n" +
                "where t1.question_type in (1,2);", uid, collId);
        return score == null ? BigDecimal.ZERO : score;
    }

    /**
     * 获取下一题需要评分的题
     * @param teacherId 教师userId
     * @param studentId 学生userId，如果指定学生，则忽略评分状态，兼容改分的情况
     * @param currentId 当前正在评分的id
     * @param action next/prev
     * @param questionIdList 题目id范围
     * @param classIdList 班级id范围
     */
    public CollUserAnswer getNextToJudge(String teacherId,
                                         String studentId,
                                         String currentId, String action,
                                         List<String> questionIdList,
                                         List<String> classIdList) {
        // 将其他lock状态的题恢复
        dao.runSql("update coll_user_answer set judge_state = 0, judging_teacher_id = null, judge_lock_at = null " +
                "where judge_state = 1 and judging_teacher_id = ?", teacherId);

        Map<String, Object> params = MapKit.startOf("teacherId", teacherId)
                .of("questionIdList", questionIdList)
                .of("classIdList", classIdList)
                .of("currentId", currentId)
                .of("action", action)
                .endOf("studentId", studentId);

        // 更新下一个需要评分的题
        CollUserAnswer userAnswer = dao.selectOne(CollUserAnswer.class, "selectAnswerForJudge", params);
        if (userAnswer != null && studentId == null) {
            userAnswer.setJudgeState(1);
            userAnswer.setJudgingTeacherId(teacherId);
            userAnswer.setJudgeLockAt(new Date());
            updateById(userAnswer);
        }

        // 如果未评分，则恢复
        if (Strings.isNotBlank(currentId)) {
            dao.runSql("update coll_user_answer set judge_state = 0, judging_teacher_id = null, judge_lock_at = null " +
                    "where id = ? and judge_state = 1", currentId);
        }

        return userAnswer;
    }

    CollUserAnswer getJudging(String teacher) {
        return dao.selectOne(CollUserAnswer.class,
                "select * from coll_user_answer where " +
                        "judge_state = 1 and judging_teacher_id = ? limit 1", teacher);
    }

    public List<CollUserAnswer> queryByUserIdAndCollId(String userId, String collId) {
        return lambdaQuery().eq(CollUserAnswer::getUserId, userId)
                .eq(CollUserAnswer::getCollId, collId)
                .list();
    }

    // 查询主观题得分
    public BigDecimal fetchSubjectiveScore(String collId, String userId) {
        return dao.selectOne(BigDecimal.class, "fetchUserAnswerSubjectiveScore",
                MapKit.startOf("collId", collId).endOf("userId", userId));
    }
}
